<template>
    <div class="page page-design">
        <v-slide-frame @change="handleSlideFrameResize">
            <p-toolbar :map="map" :tabName="tabName" :rulerMode="rulerMode" @rulerModeChange="v => (rulerMode = v)"
                :mapMode="mapMode" @mapModeChange="v => (mapMode = v)" :displayVehicleLabels="displayVehicleLabels"
                @displayVehicleLabelsChange="v => (displayVehicleLabels = v)" :dragMode="dragMode"
                @dragModeChange="v => (dragMode = v)" :tapeMode="tapeMode" @tapeModeChange="v => (tapeMode = v)"
                :hideVehiclesMode="isHideVehicles" @vehiclesHideChange="v => (isHideVehicles = v)"
                :hidePathsMode="isHidePaths" @pathsHideChange="v => (isHidePaths = v)"
                :hideContoursMode="isHideContours" @contoursHideChange="v => (isHideContours = v)"
                :hideRangesMode="isHideRanges" @rangesHideChange="v => (isHideRanges = v)" />
            <p-painter :map="map" :mode="mapMode" @mapChange="v => (map = v)" :rulerMode="rulerMode"
                :dragMode="dragMode" :tapeMode="tapeMode" :displayVehicleLabels="displayVehicleLabels"
                :vehiclesSelectable="vehiclesSelectable" :pathsSelectable="pathsSelectable"
                :contoursSelectable="contoursSelectable" :rangesSelectable="rangesSelectable"
                :hideVehicles="isHideVehicles" :hidePaths="isHidePaths" :hideContours="isHideContours"
                :hideRanges="isHideRanges" clickable @drawContours="handleDrawContours" @drawRanges="handleDrawRanges"
                @drawPaths="handleDrawPaths" @bezierChanged="handleBezierChanged" @quickJob="handleQuickJob"
                @vehiclesChange="handleVehiclesChange" @pathsChange="handlePathsChange"
                @contoursChange="handleContoursChange" @rangesChange="handleRangesChange" />
            <!-- <template v-slot:right>
                <p-panel ref="panel" @editChanged="handleEditChanged" @tabChange="v => (tabName = v)" :isDragMode="dragMode"
                    :tapeMode="tapeMode" />
            </template> -->
        </v-slide-frame>
    </div>
</template>

<script type="text/ecmascript-6">
import Kernel from '../core/Kernel.js';
import Storage from '../utils/Storage.js';
import * as mock from '../mock/index.js';
import KernelWorker from '../../workers/kernel.worker.js';
import offlineWorker from '../../workers/offline.worker.js';
// @ is an alias to /src
import * as API from '../core/api.js';
import * as enums from '../store/status-enums.js';
import { mapState } from 'vuex';
import bus from '../utils/Eventbus.js';
import pPanel from '../components/p-panel.vue';
import pPainter from '../components/p-painter.vue';
import pToolbar from '../components/p-toolbar.vue';
import vSlideFrame from '../utils/v-slide-frame.vue';

export default {
    name: "design",
    // components: { vSlideFrame, pPainter, pToolbar, pPanel }, //eslint-disable-line
    components: { vSlideFrame, pPainter, pToolbar, pPanel }, //eslint-disable-line
    data() {
        return {
            map: {},
            rulerMode: 1,
            mapMode: '', // isometric
            dragMode: false,
            tapeMode: false,
            displayVehicleLabels: false,
            localContours: [],
            localRanges: [],
            localPaths: [],
            vehiclesSelectable: false,
            pathsSelectable: false,
            contoursSelectable: false,
            rangesSelectable: false,
            isHideVehicles: false,
            isHidePaths: false,
            isHideContours: false,
            isHideRanges: false,
            tabName: ''
        };
    },
    computed: {
        ...mapState({
            openedBoxes: state => state.businessStatus.openedBoxes,
            isAltFnActive: state => state.businessStatus.isAltFnActive
        })
    },
    watch: {
        // isDrawContoursActive(val) {
        //     if (!val) this.drawContours();
        // },
        openedBoxes(val) {
            console.log('design.watch.openedBoxes:', val);
            this.vehiclesSelectable = val.indexOf('vehiclesTable') >= 0;
            this.pathsSelectable = val.indexOf('pathsTable') >= 0;
            this.contoursSelectable = val.indexOf('contoursTable') >= 0;
            this.rangesSelectable = val.indexOf('rangesTable') >= 0;
        }
    },
    created() {
        console.log('-------------------------created-------------------------');
        // 隐藏--车辆，路线，图形，区域
        // bus.on('p-painter.hide-vehicles', this.handleHideVehicles);
        // bus.on('p-painter.hide-paths', this.handleHidePaths);
        // bus.on('p-painter.hide-contours', this.handleHideContours);
        // bus.on('p-painter.hide-ranges', this.handleHideRanges);
    },
    beforeMount() {
        console.log('-------------------------beforeMount-------------------------');
    },
    mounted() {
        console.log('-------------------------mounted-------------------------');
        this.init();
    },
    beforeUnmount() {
        this.$store.commit(enums.DESELECT_CONTOURS_ALL);
        this.$store.commit(enums.DESELECT_RANGES_ALL);
        this.$store.commit(enums.DESELECT_PATHS_ALL);
        this.$store.commit(enums.DESELECT_VEHICLES_ALL);
        this.$store.commit(enums.DESELECT_JOBS_ALL);
    },
    methods: {
        init() {
            // Mock.init(); // init local data...just for demo...
            console.warn('design.init: ');
            this.initKernel();
        },
        initKernel() {
            console.log('map-2d.initKernel: ', this.$parent);
            this.kernel = Kernel.getInstance(this.$root);
            this.kernel.disconnect();
            // this.kernel.initWorker(offlineWorker);
            this.kernel.initWorker(offlineWorker);
            this.kernel.offlineConnect('map', 50, mock.getLocalResources('map'), true);
            this.kernel.on('handleWs', this.handleWsFunc);
            this.kernel.on('handleResources', this.handleResourcesFunc);
            this.kernel.on('handleIncrement', this.handleIncrementFunc);
            this.kernel.on('handlePanic', this.handlePanicFunc);
            this.kernel.on('handleOffline', this.handleOfflineFunc);
            // this.handleOfflineConnect('map');
            this.handleReconnect();
        },
         // CREDENTIALS RESOURCES
        getCredentials() {
            let token = Storage.getSessionStorage('CREDENTIALS').get('wstoken');
            if (!token) {
                this.autoLogin();
                token = Storage.getSessionStorage('CREDENTIALS').get('wstoken');
            }
            let url = process.env.VUE_APP_WEBSOCKET_URL || location.host,
                subscriptions = Storage.getSessionStorage('CREDENTIALS').get('subscriptions'),
                settings = Storage.getSessionStorage('SETTINGS').get('settings') || [],
                lifeCyclePeriod = settings.find(v => v.id === 'lifeCyclePeriod');
            return [token, url, subscriptions, lifeCyclePeriod];
        },
        autoLogin(){
            let res;
            let method = 'POST',
                subscribes = ['variables', 'models', 'contours', 'paths', 'events', 'scripts', 'jobs', 'users', 'settings', 'ranges', 'vehicles'];
            res = API.subscriptions(subscribes, { method, silent: true }).catch(e => e);
            if (!res) return this.showMessage(res);
            console.log('author.subscriptions: ', res);
            this.$root.subscriptions = subscribes;
            console.log('author.subscriptions: ', res);
            this.loading = false;
        },
        async handleReconnect() {
            let [token, url, subscriptions, lifeCyclePeriod] = this.getCredentials();
            let method = 'POST';
            token = await API.subscriptions(subscriptions, { method, silent: true }).catch(() => '');
            console.log('App.handleReconnect: ', token);
            if (!token) {
                this.$message({ type: 'error', message: this.$i18n.t('lang.login') + ' ' + this.$i18n.t('lang.error') });
                if (this.$router.name !== 'author') this.$router.replace({ name: 'author' });
                return;
            }

            this.$root.subscriptions = subscriptions;
            console.log('App.handleReconnect: ', token);
            Kernel.getInstance().connect(token, url, subscriptions, lifeCyclePeriod);
        },
        /** Kernel */
        handleOfflineConnect(name) {
            let virtualVehicles = 10;
            if (name === 'map') virtualVehicles = 10;
            if (name === 'offline') virtualVehicles = 1000;
            Kernel.getInstance().offlineConnect(name, virtualVehicles, this.getMockResources(name));
        },
        getMockResources(name) {
            let lo = Storage.getSessionStorage('RESOURCES').get(name);
            if (lo) return lo;
            let mn = name.toLowerCase(),
                res = {
                    models: require(`../mock/models.${mn}.json`),
                    contours: require(`../mock/contours.${mn}.json`),
                    paths: require(`../mock/paths.${mn}.json`)
                };
            Storage.getSessionStorage('RESOURCES').set(name, res);
            return res;
        },
        /** Kernel callback */
        handleWsFunc(res) { //eslint-disable-line
            // console.log('--------> ', res);
            // data for echarts
            if (!this.$root.deltaCache) this.$root.deltaCache = [];
            if (this.$root.deltaCache.length > 600) this.$root.deltaCache.splice(0, 1);
            this.$root.deltaCache.push({ serverTime: res.ws.serverTime, timeDelta: res.ws.serverClock, d: res.d });
            // jobs/events/scripts for echarts
            if (!this.$root.taskCache) this.$root.taskCache = [];
            if (this.$root.taskCache.length > 600) this.$root.taskCache.splice(0, 1);

            if (!this.$root.resources || !this.$root.resources.jobs) return;
            let jobList = this.$root.resources.jobs,
                jobs = 0;
            if (jobList && jobList.length) {
                jobList.forEach(v => {
                    if (v.vehicleId) jobs++;
                });
            }
            let scriptList = this.$root.resources.scripts,
                scripts = 0;
            if (scriptList && scriptList.length) {
                scriptList.forEach(v => {
                    if (v.properties && v.properties.activation === 'true') scripts++;
                });
            }
            let eventList = this.$root.resources.events,
                events = 0;
            if (eventList && eventList.length) {
                eventList.forEach(v => {
                    if (v.properties && v.isNow === 'true') events++;
                });
            }
            this.$root.taskCache.push({ serverTime: res.ws.serverTime, jobs, scripts, events });
        },
        handleResourcesFunc(res) { //eslint-disable-line
            // console.error(res);
            if (!res || !res.data || !res.data) return;
            console.warn('App.handleResourcesFunc: ', res.refreshTypes && res.refreshTypes.contours);
            if (this.loading) this.$store.commit(enums.CLOSE_LOADING);
            let updateTag = res.refreshTypes && Object.keys(res.refreshTypes).length;
            bus.emit('p-painter-contours.refresh', updateTag);
            bus.emit('p-painter-paths.refresh', updateTag);
            bus.emit('p-painter-vehicles.refresh');
            setTimeout(() => {
                // bus.$emit('p-painter.initDimensions');
                this.$store.commit(enums.ACTIVE_ALL_DATA);
            }, 0);
        },
        handleIncrementFunc(res) {
            if (!res || !res.data || !res.data) return;
        },
        handlePanicFunc(res) {
        },
        handleOfflineFunc(res) {
        },
        // 隐藏--车辆
        handleHideVehicles(hvs) {
            console.error('design.handleHideVehicles ?', hvs);
        },
        // 隐藏--路线
        handleHidePaths(hps) {
            console.error('design.handleHidePaths ?', hps);
        },
        // 隐藏--图形
        handleHideContours(hcs) {
            console.error('design.handleHideContours ?', hcs);
        },
        // 隐藏--区域
        handleHideRanges(hrs) {
            console.error('design.handleHideRanges ?', hrs);
        },

        handleSlideFrameResize() {
            bus.emit('p-painter.repaint', true);
        },
        handleVehiclesChange(ids) {
            console.log('design.handleVehiclesChange: ', ids);
            bus.emit('vehicles.toggleRowSelection', ids);
        },
        handleContoursChange(ids) {
            console.log('design.handleContoursChange: ', ids);
            bus.emit('contours.toggleRowSelection', ids);
        },
        handleRangesChange(ids) {
            console.log('design.handleRangesChange: ', ids);
            bus.emit('ranges.toggleRowSelection', ids);
        },
        handlePathsChange(ids) {
            console.log('design.handlePathsChange: ', ids);
            bus.emit('paths.toggleRowSelection', ids);
        },
        drawContours() {
            console.log('design.drawContours: ');
            if (!this.localContours || !this.localContours.length) return;
            this.$store.commit(enums.DESELECT_CONTOURS_ALL, ['-1']);
            bus.emit('p-panel.editEnableChange', true);
            bus.emit('contoursEditor.init', this.localContours);
        },
        drawRanges() {
            console.log('design.drawRanges: ');
            if (!this.localRanges || !this.localRanges.length) return;
            this.$store.commit(enums.DESELECT_RANGES_ALL, ['-1']);
            bus.emit('p-panel.editEnableChange', true);
            bus.emit('rangesEditor.init', this.localRanges);
        },
        drawPaths() {
            console.log('design.drawPaths: ');
            if (!this.localPaths || !this.localPaths.length) return;
            this.$store.commit(enums.DESELECT_PATHS_ALL, ['-1']);
            bus.emit('p-panel.editEnableChange', true);
            bus.emit('p-path-detail-form.init', this.localPaths);
        },
        handleDrawContours(res) {
            console.log('design.handleDrawContours: ', res);
            // single contour
            // this.$store.commit(enums.DESELECT_CONTOURS_ALL, ['-1']);
            // bus.emit('p-panel.editEnableChange', true);
            // bus.emit('contoursEditor.init', res);
            // this.$store.commit(enums.DEACTIVE_DRAW_CONTOURS);

            // multi selected
            this.localContours = res;
            this.drawContours();
        },
        handleDrawRanges(res) {
            console.log('design.handleDrawRanges: ', res);
            // multi selected
            this.localRanges = res;
            this.drawRanges();
        },
        handleDrawPaths(res) {
            console.log('design.handleDrawPaths: ', res);
            // this.$store.commit(enums.DESELECT_PATHS_ALL, ['-1']);
            // bus.emit('p-panel.editEnableChange', true);
            // bus.emit('p-path-detail-form.init', res);
            // this.$store.commit(enums.DEACTIVE_DRAW_PATHS);

            // multi selected
            this.localPaths = res;
            this.drawPaths();
        },
        handleBezierChanged(res) {
            // console.warn('design.handleBezierChanged: ', res);
            bus.emit('p-path-detail-form.bezierChanged', res);
        },
        handleEditChanged(res) {
            bus.emit('p-painter-vehicles.editChanged', res);
            bus.emit('p-painter-paths.editChanged', res);
        },
        async handleQuickJob(res) {
            let job = {
                vehicleKey: res.vehicleKey,
                orderList: res.orderList,
                appointmentMode: 'ASAP',
                appointmentTime: 0,
                appointmentIndex: 0,
                endEvent: 'REMOVE',
                priority: 10,
                properties: {}
            };
            if (this.isAltFnActive) {
                bus.emit('p-panel.editEnableChange', true);
                // bus.emit('jobsEditor.quickJob', job);
                bus.emit('jobsEditor.init', job);
            } else {
                let res = await API.updateJob(job);
                if (typeof res === 'undefined') return;
                setTimeout(() => bus.emit('jobs.toggleRowSelection', [res]), 0);
                // this.$store.commit(enums.DESELECT_JOBS_ALL, [res]);
                // // bus.emit('p-panel.editEnableChange', true);
                // bus.emit('jobsEditor.init');
            }
            this.$store.commit(enums.DESELECT_VEHICLES_ALL, [res.vehicleKey]);
            this.$store.commit(enums.DEACTIVE_ALTFN);
            this.dragMode = null;
        }
    }
};
</script>

<style lang="scss">
.page-design {
    width: 100%;
    height: calc(100vh - 70px);

    .p-painter {
        height: calc(100% - 38px);
    }
}
</style>
